﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;
using System.Web;

namespace HUNTERS.CORE
{
    public class Core
    {
        protected static readonly string sIV = "5D0717A739BAFD40C109AD9F91DF8450";
        private static string jsCode;

        public Core(string _jscode)
        {
            jsCode = _jscode;
        }

        #region 生成校验文本
        /// <summary> 
        /// 将c# DateTime时间格式转换为Unix时间戳格式 
        /// </summary> 
        /// <param name="time">时间</param> 
        /// <returns>long</returns> 
        private static long ConvertDateTimeToInt(DateTime time)
        {
            System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1, 0, 0, 0, 0));
            long t = (time.Ticks - startTime.Ticks) / 10000;   //除10000调整为13位     
            return t;
        }

        /// <summary>       
        /// 时间戳转为C#格式时间    timeStamp=146471041000   
        /// </summary>       
        /// <param name="timeStamp"></param>       
        /// <returns></returns>       
        private static DateTime ConvertStringToDateTime(string timeStamp)
        {
            DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
            long lTime = long.Parse(timeStamp + "0000");
            TimeSpan toNow = new TimeSpan(lTime);
            return dtStart.Add(toNow);
        }

        private static string GetUnixTime()
        {
            return ConvertDateTimeToInt(DateTime.Now).ToString();
        }

        public static string JScriptGetCode()
        {
            DateTime nowTime = DateTime.Now;

            string DataCode = "GetCode('TF1;020;;;;;;;;;;;;;;;;;;;;;;Mozilla;Netscape;5.0%20%28Windows%20NT%206.1%3B%20Win64%3B%20x64%29%20AppleWebKit/537.36%20%28KHTML%2C%20like%20Gecko%29%20Chrome/58.0.3029.110%20Safari/537.36;20030107;"
                + "undefined;true;;true;Win32;undefined;Mozilla/5.0%20%28Windows%20NT%206.1%3B%20Win64%3B%20x64%29%20AppleWebKit/537.36%20%28KHTML%2C%20like%20Gecko%29%20Chrome/58.0.3029.110%20Safari/537.36;zh-CN;undefined;;undefined;undefined;undefined;undefined;false;false;"
                + ConvertDateTimeToInt(nowTime) + ";8;2005-6-7%2021%3A33%3A44;3440;1440;;25.0;;;;;8;-480;-480;" + HttpUtility.UrlEncode(nowTime.AddDays(100).ToString("yyyy-M-d hh:mm:ss")) + ";24;3440;1400;0;0;;;;;;Shockwave%20Flash%7CShockwave%20Flash%2025.0%20r0;;;;;;;;;;;;;;;;;;;;;;;;;;;;5.6.1-0;;')";

            Type obj = Type.GetTypeFromProgID("ScriptControl");
            if (obj == null) return null;
            object ScriptControl = Activator.CreateInstance(obj);
            obj.InvokeMember("Language", BindingFlags.SetProperty, null, ScriptControl, new object[] { "JScript" });
            obj.InvokeMember("AddCode", BindingFlags.InvokeMethod, null, ScriptControl, new object[] { jsCode });
            string codeValue = obj.InvokeMember("Eval", BindingFlags.InvokeMethod, null, ScriptControl, new object[] { DataCode }).ToString();
            codeValue = "{\"U\": \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36\",\"L\": \"zh_CN\", \"Z\": \"GMT+08:00\", \"V\": \"1.1\",\"F\": \"" + codeValue + "\"}";
            return codeValue;
        }

        #endregion

        #region 加密解密单元
        public static string MD5(string str)
        {
            MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
            return BitConverter.ToString(md5.ComputeHash(Encoding.Default.GetBytes(str))).Replace("-", "").ToUpper();
        }

        private static string SHA256(string Source_String)
        {
            byte[] StrRes = Encoding.Default.GetBytes(Source_String);
            HashAlgorithm iSHA = new SHA256CryptoServiceProvider();
            StrRes = iSHA.ComputeHash(StrRes);
            StringBuilder EnText = new StringBuilder();
            foreach (byte iByte in StrRes)
            {
                EnText.AppendFormat("{0:x2}", iByte);
            }
            return EnText.ToString().ToUpper();
        }

        private static string Decrypt(string prm_key, string prm_iv, string prm_text_to_decrypt)
        {
            try
            {
                var sEncryptedString = prm_text_to_decrypt;

                var myRijndael = new RijndaelManaged()
                {
                    Padding = PaddingMode.Zeros,
                    Mode = CipherMode.CBC,
                    KeySize = 256,
                    BlockSize = 256
                };

                var key = Encoding.ASCII.GetBytes(prm_key);
                var IV = Encoding.ASCII.GetBytes(prm_iv);

                var decryptor = myRijndael.CreateDecryptor(key, IV);
                var sEncrypted = Convert.FromBase64String(sEncryptedString);
                var fromEncrypt = new byte[sEncrypted.Length];
                var msDecrypt = new MemoryStream(sEncrypted);
                var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read);
                csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length);

                return (Encoding.Default.GetString(fromEncrypt));
            }
            catch (Exception ex)
            {
                throw ex;
            }

        }

        private static string Encrypt(string prm_key, string prm_iv, string prm_text_to_encrypt)
        {
            try
            {
                var sToEncrypt = prm_text_to_encrypt;

                var myRijndael = new RijndaelManaged()
                {
                    Padding = PaddingMode.Zeros,
                    Mode = CipherMode.CBC,
                    KeySize = 256,
                    BlockSize = 256
                };

                var key = Encoding.ASCII.GetBytes(prm_key);
                var IV = Encoding.ASCII.GetBytes(prm_iv);

                var encryptor = myRijndael.CreateEncryptor(key, IV);
                var msEncrypt = new MemoryStream();
                var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write);
                var toEncrypt = Encoding.Default.GetBytes(sToEncrypt);
                csEncrypt.Write(toEncrypt, 0, toEncrypt.Length);
                csEncrypt.FlushFinalBlock();
                var encrypted = msEncrypt.ToArray();

                return (Convert.ToBase64String(encrypted));
            }
            catch (Exception ex)
            {
                throw ex;
            }

        }

        /// <summary>
        /// Base64加密
        /// </summary>
        /// <param name="Message"></param>
        /// <returns></returns>
        private static string Base64Encode(string Message)
        {
            byte[] bytes = Encoding.Default.GetBytes(Message);
            return Convert.ToBase64String(bytes);
        }
        /// <summary>
        /// Base64解密
        /// </summary>
        /// <param name="Message"></param>
        /// <returns></returns>
        private static string Base64Decode(string Message)
        {
            byte[] bytes = Convert.FromBase64String(Message);
            return Encoding.Default.GetString(bytes);
        }

        private static string StrToHex(string mStr) //返回处理后的十六进制字符串 
        {
            return BitConverter.ToString(
            ASCIIEncoding.Default.GetBytes(mStr)).Replace("-", "").ToUpper();
        } /* StrToHex */

        private static string HexToStr(string mHex) // 返回十六进制代表的字符串 
        {
            mHex = mHex.Replace(" ", "");
            if (mHex.Length <= 0) return "";
            byte[] vBytes = new byte[mHex.Length / 2];
            for (int i = 0; i < mHex.Length; i += 2)
                if (!byte.TryParse(mHex.Substring(i, 2), NumberStyles.HexNumber, null, out vBytes[i / 2]))
                    vBytes[i / 2] = 0;
            return ASCIIEncoding.Default.GetString(vBytes);
        } /* HexToStr */

        private static int GetRandomSeed()
        {
            byte[] bytes = new byte[4];
            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
            rng.GetBytes(bytes);
            return BitConverter.ToInt32(bytes, 0);
        }

        public static string GetCode(int num)
        {
            int number; char code;
            string checkCode = String.Empty;
            Random random = new Random(GetRandomSeed());
            for (int i = 0; i < num; i++)
            {
                number = random.Next();
                if (number % 2 == 0)
                    code = (char)('0' + (char)(number % 10));
                else
                    code = (char)('A' + (char)(number % 26));
                checkCode += code.ToString();
            }
            return checkCode;
        }

        public static string GetCodeLike16(int num)
        {
            int number; char code;
            string checkCode = String.Empty;
            Random random = new Random(GetRandomSeed());
            for (int i = 0; i < num; i++)
            {
                number = random.Next();
                if (number % 2 == 0)
                    code = (char)('0' + (char)(number % 10));
                else
                    code = (char)('A' + (char)(number % 6));
                checkCode += code.ToString();
            }
            return checkCode;
        }

        public static string Decrypt(string data)
        {
            var strsKey = data.Substring(0, 32);
            return HexToStr(Decrypt(strsKey, sIV, HexToStr(data.Substring(32, data.Length - 32))));
        }


        public static string Encrypt(string data)
        {
            string strsKey = GetCodeLike16(32);
            return strsKey + StrToHex(Encrypt(strsKey, sIV, StrToHex(data)));
        }

        #endregion
    }
}
